package com.sugo.seckill.web.order;

import com.sugo.seckill.http.HttpResult;
import com.sugo.seckill.http.HttpStatus;
import com.sugo.seckill.order.service.SeckillOrderService;
import com.sugo.seckill.pojo.FrontUser;
import com.sugo.seckill.pojo.TbSeckillGoods;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * controller
 * @author Administrator
 *
 */
@RestController
@RequestMapping("/seckill")
public class SeckillOrderController {

	@Autowired
	private SeckillOrderService seckillOrderService;






	/**
	 * @Description: 方式1-1：秒杀下单，不使用任何锁，会出现超卖的现象
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrder/{seckillId}",method = RequestMethod.GET)
	public HttpResult submitOrder(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");

		//判断
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//没有开启任何多线程下单
		HttpResult result = seckillOrderService.startSubmitOrder(seckillId, frontUser.getId() + "");
		return result;

	}


	/**
	 * @Description: 方式1-2：秒杀下单，不使用任何锁，会出现超卖的现象
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/submitOrderMul/{seckillId}",method = RequestMethod.GET)
	public HttpResult submitOrderMultiThread(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用了多线程的方式下单
		HttpResult result = seckillOrderService.startSubmitOrderMultiThread(seckillId, frontUser.getId() + "");
		return result;

	}


	/**
	 * @Description: 方式2-1：秒杀下单，不使用任何锁，会出现超卖的现象
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderByReentrantLock/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderByReentrantLock(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用程序锁方式进行下单
		HttpResult result = seckillOrderService.startSubmitOrderByReentrantLock(seckillId,frontUser.getId()+"");
		return result;

	}


	/**
	 * @Description: 方式3-1：秒杀下单，不使用任何锁，会出现超卖的现象
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderByAOPLock/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderByAOPLock(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用aop锁方式进行下单
		HttpResult result = seckillOrderService.startSubmitOrderByAOPLock(seckillId,frontUser.getId()+"");
		return result;

	}


	/**
	 * @Description: 方式3-1：秒杀下单，不使用任何锁，会出现超卖的现象
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderByBockingQueue/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderByBockingQueue(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用队列术方式，进行下单
		HttpResult result = seckillOrderService.startSubmitOrderByBockingQueue(seckillId,frontUser.getId()+"");
		return result;

	}


	/**
	 * @Description: 5-1 使用数据库悲观锁控制库存
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderBySQLLock/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderBySQLLock(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用数据库悲观锁，进行下单
		HttpResult result = seckillOrderService.startSubmitOrderBySQLLock(seckillId,frontUser.getId()+"");
		return result;

	}


	/**
	 * @Description: 5-1 使用数据库悲观锁控制库存
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderBySQLLock3/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderBySQLLock3(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用数据库乐观锁，进行下单
		HttpResult result = seckillOrderService.startSubmitOrderBySQLLock3(seckillId,frontUser.getId()+"");
		return result;

	}


	/**
	 * @Description: 6-1 使用redis分布式锁进行下单
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 17:31
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 17:31
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	/*@RequestMapping(value = "/startSubmitOrderByRedissonLock/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderByRedissonLock(@PathVariable Long seckillId,HttpServletRequest request){

		String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//使用redis分布式锁进行下单，进行下单
		HttpResult result = seckillOrderService.startSubmitOrderByRedissonLock(seckillId,frontUser.getId()+"");
		return result;

	}*/

	/**
	 * @Description: 7-1 使用redisson分布式锁方案控制库存，实现下单
	 * @Author: hubin
	 * @CreateDate: 2020/9/5 20:48
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/9/5 20:48
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping(value = "/startSubmitOrderByZookeeperLock/{seckillId}",method = RequestMethod.GET)
	public HttpResult startSubmitOrderByZookeeperLock(@PathVariable Long seckillId,HttpServletRequest request){

	/*	String token = request.getHeader("Authorization");
		//判断用户身份信息，是否合法
		if(StringUtils.isBlank(token)){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}

		//单体架构，用户数据从当前session中获取
		FrontUser frontUser = seckillOrderService.getUserInfoFromRedis(token);

		//判断用户是否登录
		if(frontUser == null){
			return HttpResult.error(HttpStatus.SC_FORBIDDEN,"先登录，才能抢购哦!");
		}*/

		//使用redis分布式锁进行下单，进行下单
		//HttpResult result = seckillOrderService.startSubmitOrderByZookeeperLock(seckillId,"15");
		//发送消息
		//seckillOrderService.sendMessageTransaction(seckillId+"","15");

		return HttpResult.ok();

	}

	/**
	 * @Description: 获取时间
	 * @Author: hubin
	 * @CreateDate: 2020/6/10 16:19
	 * @UpdateUser: hubin
	 * @UpdateDate: 2020/6/10 16:19
	 * @UpdateRemark: 修改内容
	 * @Version: 1.0
	 */
	@RequestMapping("/submitOrder/times")
	public HttpResult getConcurrentTime(){
		return HttpResult.ok(System.currentTimeMillis()+"");
	}


	@RequestMapping("/test")
	public HttpResult getSeckillGoods(Long seckillId){
		seckillOrderService.getSeckillGoods(seckillId);
		return HttpResult.ok();
	}
	
}
